/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import fetch from '@system.fetch'
import configuration from '@system.configuration';
import device from '@system.device';
import app from '@system.app';
import router from '@system.router';
import centralOperator from '../../scripts/centralOperator'
import config from '../../config.js'
import DefaultValueOperator from '../../scripts/defaultValueOperator.js'

const JS_TAG = 'JS/Component/Service card: ';
export const SHOW_SERVICES_COUNT = 2;
export const SHOW_DEVICES_COUNT = 4;
export const TYPE_SERVICES = 0;
export const TYPE_DEVICES = 1;
const LIMIT_COUNT = 1000; // Specifies the length of the subscription list to be obtained. The pair value is 20
const DETAIL_HEAD_TYPE = 'SubscribeIntentRequest';
const PRODUCT_PACKAGE = config.productPackage;
const BASE_URL = 'https://hag-drcn.op.hicloud.com';
const SUBSCRIBE_INFO_URL = BASE_URL + '/user-ability/v1/candidate-abilities/products/query';
const ABILITY_DETAIL_URL = BASE_URL + '/user-inquiry/v1/dist-abilities/inquiry';
const CONST_VERSION = 'version';
const CONST_CATEGORY = 'category';
const CONST_SCENE = 'scene';
const CONST_CROWD = 'crowd';
const CONST_MATCHING = 'matching';
const DEFAULT_IMAGE_PATH = '/common/img/base/ic_public_arrow_right.svg';

export default {
  props: {
    showObject: false,
  },
  data: {
    aarrowRightImagePath: DEFAULT_IMAGE_PATH,
    language: undefined,
    appBaseInfo: {},
    commonHeader: {},
    terminalInfo: {},
    commonServiceIdList: [],
    deviceServiceIdList: [],
    abilityList: [],
    deviceList: [],
    displayServices: [],
    showServicesCount: SHOW_SERVICES_COUNT,
    serviceImageWidth: undefined,
    serviceImageHeight: undefined,
  },
  onInit() {
    console.info(JS_TAG + 'onInit');
    this.arrowRightImagePath =
      DefaultValueOperator.imgPath(this.arrowRightImagePath, DEFAULT_IMAGE_PATH, this.$app.$def.globalData.isDarkMode);
    let localeInfo = configuration.getLocale();
    this.language = localeInfo.language + '_' + localeInfo.countryOrRegion;
    this.initAppSystemInfo();
  },
  initAppSystemInfo() {
    var info = app.getInfo();
    console.debug(JS_TAG + 'Get app info = ' + JSON.stringify(info));
    this.appBaseInfo.versionName = info.versionName;
    this.appBaseInfo.versionCode = info.versionCode;
    let self = this;
    try {
      device.getInfo({
        success: function (data) {
          console.info(JS_TAG + 'Device information obtained successfully. Device brand:' + JSON.stringify(data));
          self.appBaseInfo.brand = data.brand;
          self.appBaseInfo.product = data.product;
          self.appBaseInfo.model = data.model;
          self.appBaseInfo.deviceType = data.deviceType;
          self.appBaseInfo.region = data.region;
          self.onInitInfoSuccess();
        },
        fail: function (data, code) {
          console.error(JS_TAG + 'Device information obtained failed. Error code:' + code + '; Error information: ' +
          JSON.stringify(data));
          self.appBaseInfo.brand = data.brand;
          self.appBaseInfo.product = data.product;
          self.appBaseInfo.model = data.model;
          self.appBaseInfo.deviceType = data.deviceType;
          self.appBaseInfo.region = data.region;
          self.onInitInfoSuccess();
        },
      });
    } catch (e) {
      console.error(JS_TAG + 'initAppSystemInfo Device getInfo error: ' + e);
    }
  },
  onInitInfoSuccess() {
    try {
      centralOperator.getUniqueId().then(
        resultJson => {
          console.debug(JS_TAG + 'getUniqueId: ' + JSON.stringify(resultJson));
          if (resultJson.data.uniqueId) {
            this.appBaseInfo.uniqueId = resultJson.data.uniqueId;
          } else {
            this.appBaseInfo.uniqueId = config.bundleName;
            console.error(JS_TAG + 'getUniqueId uniqueId is empty');
          }
          this.initRequestInfo();
        }
      );
    } catch (e) {
      console.error(JS_TAG + 'getUniqueId error = ' + e);
    }
  },
  initRequestInfo() {
    // init the request header
    this.commonHeader = {
      'x-hag-trace-id': config.bundleName + '_' + Date.parse(new Date()),
      'x-udid': this.appBaseInfo.uniqueId,
      'x-device-id': this.appBaseInfo.uniqueId,
      'x-client-version': PRODUCT_PACKAGE + '_' + this.appBaseInfo.versionName,
      'x-prd-pkg-name': PRODUCT_PACKAGE,
      'Content-Type': 'application/json'
    }
    console.debug(JS_TAG + 'this.commonHeader = ' + JSON.stringify(this.commonHeader));
    // init the request body of subscription query
    this.terminalInfo = {
      'prdVer': this.appBaseInfo.versionName,
      'language': this.language,
      'locale': this.language,
      'countryCode': this.appBaseInfo.region,
      'phoneType': this.appBaseInfo.product,
      'deviceType': this.appBaseInfo.deviceType.toUpperCase(),
      'sysVer': 'EMUI11',
      'deltaPlatformVer': this.appBaseInfo.versionCode
    }
    console.debug(JS_TAG + 'this.terminalInfo = ' + JSON.stringify(this.terminalInfo));

    this.getSubscribeInfo();
  },
  onInquiryResult(isSuccess) {
    if (!isSuccess) {
      console.error(JS_TAG + 'inquiry failed.');
      return;
    }
    this.refreshCard();
  },
  refreshCard() {
      if (!this.abilityList || this.abilityList.length == 0) {
        console.error(JS_TAG + 'abilityList is empty');
        this.displayServices = [];
        return;
      }
      if (this.abilityList.length <= SHOW_SERVICES_COUNT) {
        this.displayServices = this.abilityList;
        for (let i = 0; i < this.displayServices.length; i++) {
          this.displayServices[i].index = i;
        }
      } else {
        for (let i = 0; i < SHOW_SERVICES_COUNT; i++) {
          let service = this.abilityList[i];
          service.index = i;
          this.displayServices.push(service);
        }
      }
    console.info(JS_TAG + 'this.services = ' + JSON.stringify(this.displayServices) );
  },
  getSubscribeInfo() {
    let GET_SUB_INFO = JS_TAG + 'get subscribe info(): ';
    let self = this;
    console.debug(GET_SUB_INFO + 'requestUrl = ' + SUBSCRIBE_INFO_URL + ', commonHeader = ' + JSON.stringify(self
    .commonHeader));
    fetch.fetch({
      url: SUBSCRIBE_INFO_URL,
      method: 'POST',
      header: this.commonHeader,
      data: {
        'terminalInfo': this.terminalInfo,
        'prdPkgName': PRODUCT_PACKAGE,
        'limit': LIMIT_COUNT
      },
      success: function (response) {
        self.onGetSubscribeSuccess(response);
      },
      fail: function (msg) {
        console.error(GET_SUB_INFO + 'fetch fail:' + msg + JSON.stringify(msg));
      }
    });
  },
  onGetSubscribeSuccess(response) {
    let self = this;
    let TAG = JS_TAG + 'onGetSubscribeSuccess: ';
    try {
      console.debug(TAG + 'getSubscribeInfo success====>' + JSON.stringify(response));
      if (!response || !response.data) {
        console.error(TAG + 'response is empty');
        return;
      }
      let abilities = JSON.parse(response.data).candidateAbilityDetailList;
      if (!abilities) {
        console.error(TAG + 'abilities empty');
        return;
      }
      for (let index of Object.keys(abilities)) {
        if (abilities[index] && abilities[index].ability) {
          const ability = abilities[index].ability;
          self.commonServiceIdList.push(ability.abilityId);
        } else {
          console.error(TAG + 'ability is empty');
        }
      }
      if (!self.commonServiceIdList) {
        console.error(TAG + 'commonServiceIdList is empty');
      } else {
        if (self.commonServiceIdList.length > 0) {
          self.inquiryAbility(self.commonServiceIdList);
        }
      }
    } catch (e) {
      console.error(TAG + 'services onResult error:' + e);
    }
  },
  inquiryAbility(identifierList) {
    let INQUIRY_ABILITY_TAG = JS_TAG  + ' inquiry ability(): ';
    let requestBody = this.getInquiryRequestBody(identifierList);
    if (!requestBody) {
      console.error(INQUIRY_ABILITY_TAG + 'requestBody is empty');
      return;
    }
    let self = this;
    fetch.fetch({
      url: ABILITY_DETAIL_URL,
      method: 'POST',
      header: this.commonHeader,
      data: requestBody,
      success: function (response) {
        try {
          console.info(INQUIRY_ABILITY_TAG + 'inquiry success====>' + JSON.stringify(response));
          if (!response) {
            console.error(INQUIRY_ABILITY_TAG + 'response is empty');
            return;
          }
          let resultIntents = JSON.parse(response.data).resultIntents;
          if (!resultIntents) {
            console.error(INQUIRY_ABILITY_TAG + 'inquiry ability resultIntents is empty, stop parse data');
            return;
          }
          console.debug(INQUIRY_ABILITY_TAG + 'inquiry ability resultIntents len = ' + JSON.stringify(resultIntents.length));
          self.parseData(resultIntents);
        } catch (e) {
          self.onInquiryResult(false);
          console.error(INQUIRY_ABILITY_TAG + e)
        }
        self.onInquiryResult(true);
      },
      fail: function (msg) {
        console.error(INQUIRY_ABILITY_TAG + 'inquiry ability detail fail: ' + JSON.stringify(msg));
        self.onInquiryResult(false);
      }
    });
  },
  getInquiryRequestBody(identifierList) {
    let queryIntents = this.getInquireIntents(identifierList);
    if (!queryIntents || queryIntents.length == 0) {
      return '';
    }
    var data = {
      'header': {
        'type': DETAIL_HEAD_TYPE
      },
      'endpoint': {
        'device': {
          'deviceId': this.appBaseInfo.uniqueId
        },
        'locale': this.language
      },
      'inquire': {
        'intents': queryIntents
      }
    }
    console.debug(JS_TAG + 'get inquiry request body = ' + JSON.stringify(data));
    return data;
  },
  getInquireIntents(identifierList) {
    var inquireIntents = [];
    try {
      if (identifierList == null || identifierList.length == 0) {
        console.error(JS_TAG + 'get InquireIntents identifierList is empty ');
        return;
      }
      for (let index of Object.keys(identifierList)) {
        let element = {
          'selectMode': 'DIRECT_EXECUTE',
          'intentSN': index,
          'channel': '0',
          'intentAbilities': [{
                                'abilityId': identifierList[index],
                                'slots': this.getCustomSlots()
                              }]
        }
        inquireIntents.push(element);
      }
      console.debug(JS_TAG + 'get inquireIntents = ' + JSON.stringify(inquireIntents));
    } catch (e) {
      console.error(JS_TAG + 'get inquireIntents exception  = ' + e);
      return;
    }
    return inquireIntents;
  },
  getCustomSlots() {
    let filter = {};
    filter.version = this.getSlotItem(CONST_VERSION, config.filterValue.version, null);
    filter.scene = this.getSlotItem(CONST_SCENE, config.filterValue.scene, null);
    filter.category = this.getSlotItem(CONST_CATEGORY, config.filterValue.category, null);
    filter.crowd = this.getSlotItem(CONST_CROWD, config.filterValue.crowd, null);
    filter.matching = this.getSlotItem(CONST_MATCHING, config.filterValue.matching, null);

    console.info(JS_TAG + 'get custom slots  = ' + JSON.stringify(filter));
    return filter;
  },
  getSlotItem(filterType, value, extendValue) {
    return {
      'name': filterType,
      'values': [
        {
          'origin': value,
          'real': value,
          'extendValue': extendValue
        }
      ]
    };
  },
  parseData(resultIntents) {
    let PARSE_TAG;
    for (let index of Object.keys(resultIntents)) {
      PARSE_TAG = JS_TAG + ' index-' + index + ' parseData: ';
      if (resultIntents[index].abilities && resultIntents[index].abilities[0]) {
        let firstAbility = resultIntents[index].abilities[0];
        let commands = firstAbility.commands;
        if (commands && commands[0] && commands[0].body) {
          console.debug(PARSE_TAG + 'abilityId-commands = ' + firstAbility.ability.ability.abilityId + ' ' +
          JSON.stringify(commands));
            this.parseServiceDetail(index, firstAbility, commands[0].body);
        } else {
          console.error(PARSE_TAG + 'commands or body is empty');
        }
      } else {
        console.error(PARSE_TAG + 'abilities is empty');
      }
    }
  },
  parseServiceDetail(index, firstAbility, commandsBody) {
    const PARSE_TAG = JS_TAG + index + '-index parseCommonSubscribeData: ';
    let info = firstAbility.ability.ability;
    console.debug(PARSE_TAG + 'info = ' + JSON.stringify(info));

    if (!commandsBody || !commandsBody.interaction || !commandsBody.interaction[0]) {
      console.error(PARSE_TAG + 'ability commandsBody is empty');
      return;
    }
    let interaction = commandsBody.interaction[0];
    console.debug(PARSE_TAG + 'getContents interaction element = ' + JSON.stringify(interaction));

    let abilityInfo = {};
    abilityInfo.index = index;
    abilityInfo.abilityId = info.abilityId;
    abilityInfo.name = info.name;
    abilityInfo.iconUrl = info.iconUrl;
    abilityInfo.brief = interaction.brief;
    abilityInfo.appLinkType = interaction.appLinkType;
    abilityInfo.linkUrl = interaction.linkUrl;
    abilityInfo.packageName = interaction.packageName;
    abilityInfo.serviceName = interaction.serviceName;
    if (interaction && interaction.abilityForms) {
      let firstAbilityForm = interaction.abilityForms[0]
      if (firstAbilityForm) {
        abilityInfo.snapshotUrl = firstAbilityForm.snapshotUrl
      }
    }
    this.abilityList.push(abilityInfo);
    console.debug(PARSE_TAG + 'this.abilityList = ' + JSON.stringify(this.abilityList));
  },
  showAllServices() {
    console.info(JS_TAG + 'showAllServices onClick');
    router.push({
      uri: 'pages/services/services',
      params: {
        data: this.abilityList,
        type: TYPE_SERVICES
      }
    });
  },
  getItemStyleByIndex(idx) {
    if (idx == SHOW_SERVICES_COUNT - 1) {
      return 'item-style-wrap-last';
    }
    return 'item-style-wrap';
  },
}